﻿using System;
using System.Text;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using UniversalApproach.Expands;

namespace UniversalApproach.Converters
{
    public static class DesConvert
    {
        /// <summary>
        /// DesIV
        /// </summary>
        static readonly byte[] _key = { 0x00, 0x04, 0x06, 0x08, 0x0A, 0x0B, 0x0E, 0x0F };

        /// <summary>
        /// Des加密
        /// </summary>
        /// <param name="content">加密内容</param>
        /// <param name="enKey">加密密钥</param>
        /// <param name="encoder">编码名称</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        public static string EnDesStr(string content, string enKey, EncoderType encoder = EncoderType.Utf8)
        {
            if (string.IsNullOrEmpty(content) || string.IsNullOrEmpty(enKey))
                throw new ArgumentNullException(string.IsNullOrEmpty(content) ? nameof(content) : nameof(enKey));

            if (enKey.Length < 8)
                throw new ArgumentException("长度未达到8位标准", nameof(enKey));

            using (var des = DES.Create())
            {
                var tmpKey = enKey.Substring(0, 8);
                var ec = Encoding.GetEncoding(encoder.ToStr());

                des.Key = ec.GetBytes(tmpKey);
                des.IV = _key.Take(8).ToArray();

                var bC = ec.GetBytes(content);
                var ms = new MemoryStream();
                CryptoStream cS = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                cS.Write(bC, 0, bC.Length);
                cS.FlushFinalBlock();
                return Convert.ToBase64String(ms.ToArray());
            }
        }


        /// <summary>
        /// Des解密
        /// </summary>
        /// <param name="content">解密内容</param>
        /// <param name="enKey">加密密钥</param>
        /// <param name="encoder">编码名称</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        public static string DeDesStr(string content, string enKey, EncoderType encoder = EncoderType.Utf8)
        {
            if (string.IsNullOrEmpty(content) || string.IsNullOrEmpty(enKey))
                throw new ArgumentNullException(string.IsNullOrEmpty(content) ? nameof(content) : nameof(enKey));

            if (enKey.Length < 8)
                throw new ArgumentException("长度未达到8位标准", nameof(enKey));

            using (var des = DES.Create())
            {
                var tmpKey = enKey.Substring(0, 8);
                var ec = Encoding.GetEncoding(encoder.ToStr());

                des.Key = ec.GetBytes(tmpKey);
                des.IV = _key.Take(8).ToArray();

                var bC = Convert.FromBase64String(content);
                var ms = new MemoryStream();
                CryptoStream cS = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cS.Write(bC, 0, bC.Length);
                cS.FlushFinalBlock();
                return ec.GetString(ms.ToArray());
            }
        }
    }
}